package api

import (
	"encoding/json"
	"fmt"
	"gitee.com/DonHz/cloud-file-storage/common"
	"gitee.com/DonHz/cloud-file-storage/config"
	"gitee.com/DonHz/cloud-file-storage/db"
	"gitee.com/DonHz/cloud-file-storage/meta"
	"gitee.com/DonHz/cloud-file-storage/mq"
	"gitee.com/DonHz/cloud-file-storage/util"
	"github.com/gin-gonic/gin"
	"io"
	"net/http"
	"os"
	"time"
)

func UploadHandler(c *gin.Context) {
	// 接收文件流，并存储到本地目录
	file, header, err := c.Request.FormFile("file")
	if err != nil {
		fmt.Println("Failed to get data, error：", err)
		return
	}
	defer file.Close()

	// 创建文件的元信息
	fileMeta := meta.FileMeta{
		FileName: header.Filename,
		Location: "./tmp/" + header.Filename,
		UploadAt: time.Now().Format("2006-01-02 15:04:05"),
	}

	// 创建一个本地文件来接收文件流
	newFile, err := os.Create(fileMeta.Location)
	if err != nil {
		fmt.Println("Failed to create file, error：", err)
		return
	}
	defer newFile.Close()

	// 将接收的文件流复制到创建的本地文件中
	fileMeta.FileSize, err = io.Copy(newFile, file)
	if err != nil {
		fmt.Println("Failed to save data into file, error：", err)
		return
	}

	// 计算文件的Sha1值，并更新记录的总文件元信息
	newFile.Seek(0, 0)
	fileMeta.FileSha1 = util.FileSha1(newFile)

	newFile.Seek(0, 0)
	ossPath := "oss/" + fileMeta.FileSha1
	//err = oss.Bucket().PutObject(ossPath, newFile)
	//if err != nil {
	//	fmt.Println(err)
	//	c.JSON(http.StatusOK, gin.H{
	//		"msg":      "上传失败",
	//		"fileName": header.Filename,
	//	})
	//	return
	//}
	data := mq.TransferData{
		FileHash:      fileMeta.FileSha1,
		CurLocation:   fileMeta.Location,
		DestLocation:  ossPath,
		DestStoreType: common.StoreOSS,
	}
	pubData, err := json.Marshal(data)
	if err != nil {
		fmt.Println("Failed to marshal data, error：", err)
		return
	}
	IsSucess := mq.Publish(config.TransExchangeName, config.TransOSSRoutingKey, pubData)
	if !IsSucess {
		// TODO:重试发送消息逻辑
		fmt.Println("Failed to publish message to mq")
	}
	fileMeta.Location = ossPath

	ok := meta.UpdateFileMetaDB(fileMeta)
	if !ok {
		fmt.Println("Failed to update file meta to mysql")
		return
	}
	fmt.Println(fileMeta)
	// TODO: 更新用户文件表记录
	username := c.Query("username")
	ok = db.OnUserFileUploadFinished(username, fileMeta.FileSha1, fileMeta.FileName, fileMeta.FileSize)
	if !ok {
		fmt.Println("Failed to update user file table")
		return
	}
	// 返回响应
	c.Header("Access-Control-Allow-Origin", "*")
	c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
	c.JSON(http.StatusOK, gin.H{
		"code":     200,
		"msg":      "上传成功",
		"fileName": header.Filename,
	})
	//c.Redirect(http.StatusFound, "/static/view/home.html")
}
